package com.ruoyi.common.utils;

import cn.hutool.core.util.IdUtil;
import org.springframework.mock.web.MockMultipartFile;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;

public class ImageWatermarkUtil {

    // 水印透明度（0.0f完全透明，1.0f完全不透明）
    private static final float WATERMARK_ALPHA = 0.2f;
    // 水印旋转角度（145°，转换为弧度制）
    private static final double WATERMARK_ANGLE = Math.toRadians(-45);
    // 水印间距（进一步增大间距，减少水印数量）
    private static final int WATERMARK_SPACING = 550;

    /**
     * 从网络图片URL添加文字水印并转换为MultipartFile
     *
     * @param imageUrl      图片URL
     * @param watermarkText 水印文字
     * @return 处理后的MultipartFile
     * @throws IOException 处理过程中发生的IO异常
     */
    public static MultipartFile addWatermarkAndConvertToMultipartFile(String imageUrl, Map<String, Object> watermarkText) throws IOException {
        // 1. 从URL获取图片输入流
        try (InputStream inputStream = new URL(imageUrl).openStream()) {
            // 2. 读取图片
            BufferedImage originalImage = ImageIO.read(inputStream);

            // 3. 添加水印
            BufferedImage watermarkedImage = addTextWatermark(originalImage, watermarkText);

            // 4. 将处理后的图片转换为MultipartFile
            return convertImageToMultipartFile(watermarkedImage, "watermarked_" + IdUtil.getSnowflakeNextId() + ".jpg");
        }
    }

    public static BufferedImage addTextWatermark(BufferedImage originalImage, Map<String, Object> watermarkText) {
        // 1. 参数合法性校验
        if (originalImage == null) {
            throw new IllegalArgumentException("原始图片不能为空！");
        }
        if (watermarkText == null
                || watermarkText.get("nickName") == null
                || watermarkText.get("deptName") == null
                || watermarkText.get("createTime") == null
                || watermarkText.get("attendanceType") == null) {
            throw new IllegalArgumentException("水印参数Map缺少关键字段！");
        }

        // 2. 提取水印字段并拼接
        String nickName = String.valueOf(watermarkText.get("nickName"));
        String deptName = String.valueOf(watermarkText.get("deptName"));
        String createTime = String.valueOf(watermarkText.get("createTime"));
        String attendanceType = String.valueOf(watermarkText.get("attendanceType"));
        String watermarkContent = String.format("%s | %s | %s | %s", nickName, deptName, createTime, attendanceType);

        // 3. 创建与原始图片同类型的画布
        int imageWidth = originalImage.getWidth();
        int imageHeight = originalImage.getHeight();
        BufferedImage watermarkedImage = new BufferedImage(
                imageWidth,
                imageHeight,
                originalImage.getWidth() > 0 && originalImage.getHeight() > 0 ? originalImage.getType() : BufferedImage.TYPE_INT_RGB
        );

        // 4. 获取2D绘图上下文
        Graphics2D g2d = watermarkedImage.createGraphics();
        try {
            // 5. 绘制原始图片
            g2d.drawImage(originalImage, 0, 0, imageWidth, imageHeight, null);

            // 6. 设置水印基础属性 - 改为#5d5c5e颜色
            g2d.setColor(Color.decode("#2b2b2b"));
            Font watermarkFont = getSuitableFont(imageWidth, imageHeight);
            g2d.setFont(watermarkFont);
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, WATERMARK_ALPHA));

            // 7. 计算水印关键参数
            FontMetrics fontMetrics = g2d.getFontMetrics(watermarkFont);
            int textWidth = fontMetrics.stringWidth(watermarkContent);
            int textHeight = fontMetrics.getAscent();

            // 8. 旋转画布并绘制水印
            g2d.rotate(WATERMARK_ANGLE);

            // 计算铺满所需的重复次数
            int diagonal = (int) Math.sqrt(imageWidth * imageWidth + imageHeight * imageHeight);
            int horizontalCount = (diagonal * 2) / (textWidth + WATERMARK_SPACING);
            int verticalCount = (diagonal * 2) / (WATERMARK_SPACING);

            // 循环绘制水印
            for (int i = -horizontalCount; i <= horizontalCount; i++) {
                for (int j = -verticalCount; j <= verticalCount; j++) {
                    int x = i * (textWidth + WATERMARK_SPACING);
                    int y = j * WATERMARK_SPACING + textHeight;
                    g2d.drawString(watermarkContent, x, y);
                }
            }

        } finally {
            g2d.dispose();
        }

        return watermarkedImage;
    }

    /**
     * 获取适合的字体 - 使用Java内置字体确保中文显示
     */
    private static Font getSuitableFont(int imageWidth, int imageHeight) {
        // 计算字体大小
        int baseSize = Math.min(Math.max(imageWidth, 1), Math.max(imageHeight, 1)) / 20;
        int fontSize = Math.max(baseSize, 24);

        // 使用Java内置的有衬线字体，支持中文且几乎所有环境都存在
        // Font.SERIF在不同平台会映射到系统默认的有衬线字体
        // 通常在Windows上是SimSun(宋体)，Linux上可能是AR PL SungtiL GB等
        return new Font(Font.SERIF, Font.BOLD, fontSize);
    }

    /**
     * 将BufferedImage转换为MultipartFile
     *
     * @param image    图片对象
     * @param fileName 文件名
     * @return 转换后的MultipartFile
     * @throws IOException 转换过程中发生的IO异常
     */
    private static MultipartFile convertImageToMultipartFile(BufferedImage image, String fileName) throws IOException {
        // 将图片写入字节数组输出流
        try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
            ImageIO.write(image, "jpg", baos);

            // 将字节数组转换为输入流
            try (InputStream is = new ByteArrayInputStream(baos.toByteArray())) {
                // 创建MockMultipartFile作为MultipartFile的实现
                return new MockMultipartFile(
                        "file",        // 参数名
                        fileName,      // 文件名
                        "image/jpeg",  // 内容类型
                        is             // 输入流
                );
            }
        }
    }
}
